package tcln.sors.client.core.mvc;

import java.util.List;
import java.util.Map;

import tcln.commons.exception.BaseRuntimeException;

/**
 * Interface for a model data which would be used inside a {@link Controller}.
 * 
 * @param <M>
 *            Parameter type for DSL in this model.
 * @author Truong Chau Lien Ngoc (lienngoc@gmail.com)
 */
public interface ModelData<M extends ModelData<?>> {

    /**
     * A simple trick to return current instance whose type is in generics parameter.
     * 
     * @return
     */
    M getThis();

    /**
     * Returns a property value.
     * 
     * @param <V>
     * @param property
     * @param propertyClass
     *            desired property class. {@link BaseRuntimeException} is thrown if property class is not compatible
     *            with the real value.
     * @return Property value casted to desired class.
     */
    <V> V get(String property, Class<V> propertyClass);

    /**
     * Sets a new value for this property.
     * 
     * @param <V>
     * @param property
     * @param value
     * @return Current model data instance.
     */
    <V> M set(String property, V value);

    /**
     * Clears all data and states.
     * 
     * @return Current model data instance.
     */
    M clear();

    /**
     * Returns a list of all properties' values, according to the insertion order.
     * 
     * @return
     */
    List<Object> getPropertyValues();

    /**
     * Checks if given property is 'dirty' - i.e. this property has been changed since the last assignment.
     * 
     * @param property
     * @return
     */
    boolean isDirty(String property);

    /**
     * Checks if there is a dirty property in current model data.
     * 
     * @return
     */
    boolean isDirty();

    /**
     * Returns a {@link Map} containing all (property name, value) pairs.
     * 
     * @param full
     *            <code>true</code> to include all properties; <code>false</code> to ignore 'non-dirty' properties.
     * @return A new {@link Map} instance.
     */
    Map<String, Object> toMap(boolean full);
}
